/**
 * @fileOverview 二维向量运算
 * @author goodzsq@gmail.com
 */

/**
 * @class 二维向量
 * @description 二维向量
 * @param {Number} x
 * @param {Number} y
 */
var Vector2 = function(x, y) {
    this.x = x;
    this.y = y;
};

Vector2.prototype = {
    /**
     * 克隆
     * @returns {Vector2}
     */
    clone: function() {
        return new Vector2(this.x, this.y);
    },
    /**
     * 向量长度
     * @returns {Number}
     */
    length: function() {
        return Math.sqrt(this.x * this.x + this.y * this.y);
    },
    /**
     * 向量长度的平方
     * @returns {Number}
     */
    sqrLength: function() {
        return this.x * this.x + this.y * this.y;
    },
    /**
     * 单位向量，长度为1的向量
     * @returns {Vector2}
     */
    normalize: function() {
        var inv = 1 / this.length();
        return new Vector2(this.x * inv, this.y * inv);
    },
    /**
     * 负向量
     * @returns {Vector2}
     */
    negate: function() {
        return new Vector2(-this.x, -this.y);
    },
    /**
     * 加法
     * @param {Vector2} v
     * @returns {Vector2}
     */
    add: function(v) {
        return new Vector2(this.x + v.x, this.y + v.y);
    },
    /**
     * 减法
     * @param {Vector2} v
     * @returns {Vector2}
     */
    subtract: function(v) {
        return new Vector2(this.x - v.x, this.y - v.y);
    },
    /**
     * 数乘
     * @param {Number} f
     * @returns {Vector2}
     */
    multiply: function(f) {
        return new Vector2(this.x * f, this.y * f);
    },
    /**
     * 数除
     * @param {Number} f
     * @returns {Vector2}
     */
    divide: function(f) {
        var invf = 1 / f;
        return new Vector2(this.x * invf, this.y * invf);
    },
    /**
     * 点积(内积、数量积)
     * @param {Vector2} v
     * @returns {Number}
     */
    dot: function(v) {
        return this.x * v.x + this.y * v.y;
    },
    /**
     * 叉积(向量积)
     * @param {Vector2} v
     * @returns {Number}
     */
    cross: function(v) {
        return this.x * v.y - v.x * this.y;
    }
};

Vector2.zero = new Vector2(0, 0);

module.exports = Vector2;